package cn.com.bo.util.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ZipUtil {
	
	private ZipUtil(){
		
	}
	
	public static void main(String[] args) {
		InputStream input = zipInputStreamByUrls("asd",null,null,"");
		if (input != null) {
			System.out.println("a");
		}
	}
	
	private static Logger log = LoggerFactory.getLogger(ZipUtil.class);
	
	/**
	 *  多个网络文件直接压缩成zip文件流
	 * @param path
	 * @return
	 * @throws IOException
	 */
	public static InputStream zipInputStreamByUrls(String anno, String ... path){
		File tmpFile = null;
		try {
			tmpFile = File.createTempFile("TheZip", ".zip");
		} catch (IOException e1) {
		}
		zipFile(tmpFile, anno, path);
		FileInputStream fis = null;
		if (getZipTrueSize(tmpFile.getPath()) > 1) {
			try {
				fis = new FileInputStream(tmpFile);
			} catch (FileNotFoundException e) {
				log.error("转换输入流失败！失败信息{}", e);
			}
		}
		
		return fis;
	}
	
	/**
	 * 输入流转换为zip压缩文件
	 * @param input
	 * @param zipFile
	 * @param fileName
	 * @param anno
	 */
	public static void zipFile(InputStream input, File zipFile, String fileName, String anno){
        ZipOutputStream zipOut = null ; // 声明压缩流对象  
        try {
			zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ;
		} catch (FileNotFoundException e1) {
			log.error("压缩文件[{}]不存在!",zipFile.getPath());
		}
        try {
        	zipOut.putNextEntry(new ZipEntry(fileName)) ; // 设置ZipEntry对象  
            zipOut.setComment(anno) ;    // 设置注释  
            int temp = 0 ;  
            while((temp=input.read())!=-1){ // 读取内容  
                zipOut.write(temp) ;    // 压缩输出  
            }  
            input.close(); // 关闭输入流  
            zipOut.close();    // 关闭输出流 
		} catch (Exception e) {
			log.error("file压缩失败，错误信息{}",e);
		} finally {
            IOUtil.closeQuietly(zipOut, input);
		}
        
	}
	
	/**
	 * 把指定文件转换为zip文件
	 * @param file
	 * @param zipFile
	 * @param anno
	 */
	public static void zipFile(File file, File zipFile, String anno){
		try {
			zipFile(new FileInputStream(file), zipFile, file.getName(), anno);
		} catch (FileNotFoundException e) {
			log.error("file转换输入流失败，失败信息{}",e.getMessage());
		}
	}
	
	/**
	 * 将网络文件转换为zip文件压缩
	 * @param path
	 * @param zipFile
	 * @param anno
	 */
	public static void zipFile(String path, File zipFile, String anno){
		zipFile(Image2Binary.getInputStreamByUrl(path), zipFile, getName(path), anno);
	}
	
	/**
	 * 多个file文件压缩成一个zip文件
	 * @param files
	 * @param zipFile
	 * @param anno
	 */
	public static void zipFile(File[] files, File zipFile, String anno){
		ZipOutputStream zipOut = null ; // 声明压缩流对象  
		InputStream input = null;
        try {
			zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ;
		} catch (FileNotFoundException e1) {
			log.error("压缩文件[{}]不存在!",zipFile.getPath());
		}
        try {
        	for (File f : files) {
        		input = new FileInputStream(f);
        		zipOut.putNextEntry(new ZipEntry(f.getName())) ; // 设置ZipEntry对象  
                zipOut.setComment(anno) ;    // 设置注释  
                int temp = 0 ;  
                while((temp=input.read())!=-1){ // 读取内容  
                    zipOut.write(temp) ;    // 压缩输出  
                }  
                input.close() ; // 关闭输入流  
			}
            zipOut.close() ;    // 关闭输出流 
		} catch (Exception e) {
			log.error("file压缩失败，错误信息{}",e);
		} finally {
            IOUtil.closeQuietly(zipOut, input);
		}
	}
	
	/**
	 * 多个网络文件压缩成一个zip
	 * @param files
	 * @param zipFile
	 * @param anno
	 */
	public static void zipFile(File zipFile, String anno, String... path){
		ZipOutputStream zipOut = null ; // 声明压缩流对象  
		InputStream input = null;
        try {
			zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ;
		} catch (FileNotFoundException e1) {
			log.error("压缩文件[{}]不存在!",zipFile.getPath());
		}
        try {
        	for (String s : path) {
        		if (StringUtils.isNotBlank(s)) {
        			input = Image2Binary.getInputStreamByUrl(s);
            		zipOut.putNextEntry(new ZipEntry(getName(s))) ; // 设置ZipEntry对象  
                    zipOut.setComment(anno) ;    // 设置注释  
                    int temp = 0 ;  
                    while((temp=input.read())!=-1){ // 读取内容  
                        zipOut.write(temp) ;    // 压缩输出  
                    }  
                    input.close() ; // 关闭输入流  
				}
			}
        	zipOut.close() ;    // 关闭输出流 
		} catch (Exception e) {
			log.error("file压缩失败，错误信息{}",e.getMessage());
		} finally {
            IOUtil.closeQuietly(zipOut, input);
		}
	}
	
	public static String getName(String path){
		path = path.substring(path.lastIndexOf("/")+1);
		return path;
	}
	
	public static long getZipTrueSize(String filePath) {
        long size = 0;
        ZipFile f;
        try {
            f = new ZipFile(filePath);
            Enumeration<? extends ZipEntry> en = f.entries();
            while (en.hasMoreElements()) {
                size += en.nextElement().getSize();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return size;
    }
	
}
